package com.elminster.common.db.manager;

import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.ParameterMetaData;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;
import java.util.List;

import com.elminster.common.db.analyze.ISqlAnalyzer;
import com.elminster.common.db.analyze.SimpleSqlAnalyzer;
import com.elminster.common.db.analyze.SqlAnalyzerFactory;
import com.elminster.common.db.annotation.Sql;
import com.elminster.common.db.annotation.SqlFile;
import com.elminster.common.db.exception.SqlAnalyzeException;
import com.elminster.common.util.ObjectUtil;
import com.elminster.common.util.StringUtil;

/**
 * Proxy pattern for DAO classes
 * 
 * @author Gu
 * @version 1.0
 *
 */
public class DAOInvokeHandler extends InterfaceInvocationHandler {
	
	private ISqlAnalyzer sqlAnalyzer = new SimpleSqlAnalyzer();
	private SqlAnalyzerFactory sqlAnalyzerFactory = SqlAnalyzerFactory.getInstance();
	// TODO Temp
	private Connection conn;
	
	private Statement getStatement(Method method, Object[] args) throws SQLException {
		PreparedStatement pstmt = null;
		sqlAnalyzer = sqlAnalyzerFactory.getSqlAnalyzer(method, args);
		sqlAnalyzer.parser(method, args);
		String sql = sqlAnalyzer.getAnalyzedSql();
		List<Object> paramList = sqlAnalyzer.getAnalyzedSqlParameters();
		ISqlAnalyzer.SqlType sqlType = sqlAnalyzer.getSqlType();
		pstmt = conn.prepareStatement(sql);
		ParameterMetaData pmd = pstmt.getParameterMetaData();
		if (null != paramList) {
			if (pmd.getParameterCount() != paramList.size()) {
				throw new SqlAnalyzeException("Parameters count is NOT matched.");
			}
			for (int i = 0; i < paramList.size(); i++) {
				Object obj = paramList.get(i);
				if (null == obj) {
					int type = Types.VARCHAR;
					try {
						type = pmd.getParameterType(i + 1);
					} catch (SQLException e) {
					}
					pstmt.setNull(i + 1, type);
				} else {
					pstmt.setObject(i + 1, obj);
				}
			}
		}
		return pstmt;
	}

	@Override
	protected Object override(Object proxy, Method method, Object[] args) throws Throwable {
		Statement statement = getStatement(method, args);
		// TODO
		return "";
	}
	
}
